package top.lixunda.ecommerce.server.good.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.business.BaseConvertServiceImpl;
import top.lixunda.ecommerce.server.business.api.entity.cache.CacheUser;
import top.lixunda.ecommerce.server.business.api.entity.dto.PageConvertDTO;
import top.lixunda.ecommerce.server.business.api.entity.dto.PageConvertWrapperDTO;
import top.lixunda.ecommerce.server.good.api.entity.db.*;
import top.lixunda.ecommerce.server.good.api.entity.dto.FileCollectionDTO;
import top.lixunda.ecommerce.server.good.api.entity.dto.OrderReviewDetailQueryDTO;
import top.lixunda.ecommerce.server.good.api.entity.dto.OrderReviewInsertDTO;
import top.lixunda.ecommerce.server.good.api.entity.vo.OrderConvertVO;
import top.lixunda.ecommerce.server.good.api.entity.vo.OrderReviewConvertVO;
import top.lixunda.ecommerce.server.good.mapper.OrderReviewDetailMapper;
import top.lixunda.ecommerce.server.good.mapper.OrderReviewMapper;
import top.lixunda.ecommerce.server.good.service.*;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 订单评论查询接口
 *
 * @author Xumda
 * @since 2019-12-19
 */
@Service
public class OrderReviewDetailServiceImpl
        extends BaseConvertServiceImpl<OrderReviewDetailMapper, OrderReviewDetailDO, OrderReviewServiceImpl,
        OrderReviewMapper, OrderReviewDO, OrderReviewConvertVO>
        implements IOrderReviewDetailService {

    private final IStoreService storeService;

    private final IOrderReviewService orderReviewService;

    private final IOrderDetailService orderDetailService;

    private final IOrderReviewImageService orderReviewImageService;

    private final IOrderReviewMoreService orderReviewMoreService;

    private final IOrderReviewMoreImageService orderReviewMoreImageService;

    @Autowired
    public OrderReviewDetailServiceImpl(IStoreService storeService,
                                        IOrderReviewService orderReviewService,
                                        IOrderDetailService orderDetailService,
                                        IOrderReviewImageService orderReviewImageService,
                                        IOrderReviewMoreService orderReviewMoreService,
                                        IOrderReviewMoreImageService orderReviewMoreImageService) {
        super(OrderReviewConvertVO::fromOrderReviewDetailList,
                OrderReviewDO::getId, OrderReviewDetailDO::getId);
        this.storeService = storeService;
        this.orderReviewService = orderReviewService;
        this.orderDetailService = orderDetailService;
        this.orderReviewImageService = orderReviewImageService;
        this.orderReviewMoreService = orderReviewMoreService;
        this.orderReviewMoreImageService = orderReviewMoreImageService;
    }

    /**
     * 根据id查询评论信息详情
     *
     * @param id 评论id
     * @return 评论信息详细信息
     */
    @Override
    public OrderReviewConvertVO queryOrderReviewById(Integer id) {
        if (ObjectValidators.isEmpty(id)) {
            throw getAppException("评论id不能为空");
        }
        return this.getConvertById(String.valueOf(id));
    }

    /**
     * 根据id查询评论信息详情
     *
     * @param ids 评论id
     * @return 评论信息详细信息
     */
    @Override
    public List<OrderReviewConvertVO> queryOrderReviewByIds(List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            throw getAppException("评论ids不能为空");
        }
        return this.listConvertByIds(ids.stream()
                .map(String::valueOf)
                .collect(Collectors.toList()));
    }

    /**
     * 分页条件查询
     *
     * @param pageConvertDTO 分页条件查询DTO
     * @return 分页数据
     */
    @Override
    public IPage<OrderReviewConvertVO> queryOrderReviewByPageWrapper(
            PageConvertDTO<OrderReviewDO, OrderReviewDetailDO, OrderReviewDetailQueryDTO> pageConvertDTO) {
        if (ObjectValidators.isEmpty(pageConvertDTO)) {
            throw getAppException("查询条件不能为空");
        }
        return this.pageConvert(new PageConvertWrapperDTO<OrderReviewDO, OrderReviewDetailDO, OrderReviewConvertVO>()
                .setPage(pageConvertDTO.getPage())
                .setPageWrapper(pageConvertDTO.getPageWrapper())
                .setQueryWrapper(pageConvertDTO.getQueryWrapper()));
    }

    /**
     * 普通用户调用，订单评论
     *
     * @param orderReviewInsertDTO 评论数据
     * @return 是否评论成功
     */
    @SuppressWarnings("AlibabaMethodTooLong")
    @Override
    public OrderReviewConvertVO reviewOrderByOrderId(OrderReviewInsertDTO orderReviewInsertDTO) {
        CacheUser cacheUser = currentUserCacheNotNull();
        // 校验订单是否存在
        List<OrderConvertVO> orderList = orderDetailService.queryOrderDetailByIds(
                Collections.singletonList(orderReviewInsertDTO.getOrderId()));
        if (ObjectValidators.isEmpty(orderList)) {
            throw getAppException("评论失败！订单不存在!");
        }
        OrderConvertVO orderConvertVO = orderList.get(0);
        // 校验订单是否可评论
        String state = orderConvertVO.getState();
        if (!GoodOrderDO.STATE_END.equals(state) && !GoodOrderDO.STATE_RECEIVED.equals(state)) {
            throw getAppException("评论失败！订单未完结，不能评论!");
        }
        // 查询店铺数据
        StoreDO storeDO = storeService.getById(orderConvertVO.getStoreId());
        if (ObjectValidators.isEmpty(storeDO)) {
            throw getAppException("评论失败！订单店铺查询失败!");
        }
        // 鉴别评论和追加评论
        OrderReviewDO orderReviewDO = orderReviewService.getOne(new LambdaQueryWrapper<OrderReviewDO>()
                .eq(OrderReviewDO::getOrderId, orderReviewInsertDTO.getOrderId())
                .eq(OrderReviewDO::getUserId, cacheUser.getAccount()), false);
        boolean isFirst = ObjectValidators.isEmpty(orderReviewDO);
        LocalDateTime localDateTime = LocalDateTime.now();
        boolean success;
        if (isFirst) {
            // 第一次评论
            orderReviewDO = new OrderReviewDO();
            BeanUtils.copyProperties(orderReviewInsertDTO, orderReviewDO);
            orderReviewDO.setTime(localDateTime)
                    .setStoreId(storeDO.getId())
                    .setStoreName(storeDO.getName())
                    .setUserId(cacheUser.getAccount())
                    .setUserName(cacheUser.getName());
            success = orderReviewService.save(orderReviewDO);
            if (!success) {
                throw getAppException("评论失败！插入评论数据失败!");
            }
            final OrderReviewDO temp = orderReviewDO;
            List<FileCollectionDTO> fileCollectionList = orderReviewInsertDTO.getFileCollectionList();
            if (ObjectValidators.isNotEmpty(fileCollectionList)) {
                // 图片数据
                List<OrderReviewImageDO> list = fileCollectionList.stream()
                        .map(item -> {
                            OrderReviewImageDO orderReviewImageDO = new OrderReviewImageDO();
                            orderReviewImageDO.setOrderReviewId(temp.getId())
                                    .setCreateTime(localDateTime)
                                    .setFileId(item.getFileId())
                                    .setImage(item.getUrl());
                            return orderReviewImageDO;
                        })
                        .collect(Collectors.toList());
                success = orderReviewImageService.saveBatch(list);
                if (!success) {
                    throw getAppException("评论失败！插入评论图片数据失败!");
                }
            }
        } else {
            // 追加评论
            OrderReviewMoreDO orderReviewMoreDO = new OrderReviewMoreDO();
            BeanUtils.copyProperties(orderReviewInsertDTO, orderReviewMoreDO);
            orderReviewMoreDO.setTime(localDateTime)
                    .setOrderReviewId(orderReviewDO.getId())
                    .setUserId(cacheUser.getAccount())
                    .setUserName(cacheUser.getName());
            success = orderReviewMoreService.save(orderReviewMoreDO);
            if (!success) {
                throw getAppException("评论失败！插入追加评论数据失败!");
            }
            final OrderReviewMoreDO temp = orderReviewMoreDO;
            List<FileCollectionDTO> fileCollectionList = orderReviewInsertDTO.getFileCollectionList();
            if (ObjectValidators.isNotEmpty(fileCollectionList)) {
                // 图片数据
                List<OrderReviewMoreImageDO> list = fileCollectionList.stream()
                        .map(item -> {
                            OrderReviewMoreImageDO orderReviewMoreImageDO = new OrderReviewMoreImageDO();
                            orderReviewMoreImageDO.setOrderReviewMoreId(temp.getId())
                                    .setCreateTime(localDateTime)
                                    .setFileId(item.getFileId())
                                    .setImage(item.getUrl());
                            return orderReviewMoreImageDO;
                        })
                        .collect(Collectors.toList());
                success = orderReviewMoreImageService.saveBatch(list);
                if (!success) {
                    throw getAppException("评论失败！插入追加评论图片数据失败!");
                }
            }
        }
        return this.queryOrderReviewById(orderReviewDO.getId());
    }

    /**
     * 普通用户调用，订单评论，批量
     *
     * @param orderReviewInsertList 评论数据
     * @return 是否评论成功
     */
    @Override
    public List<OrderReviewConvertVO> reviewOrdersByOrderIds(List<OrderReviewInsertDTO> orderReviewInsertList) {
        if (ObjectValidators.isEmpty(orderReviewInsertList)) {
            throw getAppException("评论失败！参数不能为空");
        }
        return orderReviewInsertList.parallelStream()
                .map(this::reviewOrderByOrderId)
                .collect(Collectors.toList());
    }
}
